/************************************************************
                         Summary
**************************************************************/
#include "clam.h"
#include <malloc.h>
#include <float.h>
#include <gtk/gtkwidget.h>  /*fred 3/5/03*/

extern GtkWidget *ctg_window;  /*fred 3/5/03*/

extern void getdatehead(), clearMsg(), ZmapHigh();

Graph gsum;
void Zsummary();
static void summary();

/* you may enter your own data here. if filename=mapname, give stats */
static int numchr=11+1;
static char mapname[10] = "maize";
static int chrsize[11+1] = {0, 337,278,259,271,250,208,199,202,191,170};
static int nopop=0;

static int numPL=0, maxPL=0;
static struct Proj_line {
   int n, n2;
   int index;
   int box;
   char msg[MSGSIZE*2+1];
} *PL;

static char Msg[500];

static void sumresize()
{
    Zsummary();
}
/***********************************************************
                    DEF: quitSum
***********************************************************/
void quitSum()
{
  if (PL!=NULL) free(PL); 
  PL=NULL;
  numPL = maxPL=0;
  if(graphActivate(gsum)) graphDestroy();
}
/***********************************************************
                    DEF: printProj
***********************************************************/
static void printProj()
{
FILE *fp, *graphQueryOpen();
register int i;

    fp = graphQueryOpen(mergedir, mergefile, "","w","Choose output file");
    if(fp==0)  return;
    for (i=0; i<numPL; i++) fprintf(fp,"%s\n",PL[i].msg);
    fclose(fp);
}
/***********************************************************
                     DEF: doline
*********************************************************/
static void doline(int i, int n, int n2, int format, char *msg)
{
char  str1[1000], c[20], m[20], s[20];
int j;

   if (numPL >= maxPL-1) {
     if (maxPL==0) {
         maxPL=1000;
         PL = (struct Proj_line *) calloc(sizeof(struct Proj_line), maxPL);
     }
     else {
         maxPL+=500;
         PL = (struct Proj_line *) realloc(PL, sizeof(struct Proj_line)*maxPL);
     }
   }
   j = numPL;
   numPL++;
   PL[j].n = n;
   PL[j].n2 = n2;
   PL[j].index = i;
   PL[j+1].index = -1;

   if (format==2) { /* marker data */
      strncpy(PL[j].msg, msg, MSGSIZE*2);
      return;
   }
   sprintf(c,"%5d",contigs[i].count);    

   if(contigs[i].markers != 0) sprintf(m,"%5d",contigs[i].markers);
   else strcpy(m,"    -");

   if(contigs[i].seq != 0) sprintf(s,"%3d",contigs[i].seq);
   else strcpy(s,"  -");

   sprintf(str1, " %s %s  %s  %s",c,m,s,msg);
   strncpy(PL[j].msg, str1, MSGSIZE*2);
}
/***********************************************************
                    DEF: Zsummary
***********************************************************/
void Zsummary()
{
  static MENUOPT menu2[] = { 
	{ quitSum,"Close "},
    {  printProj, "Print to file"}, 
    {  graphPrint, "Print Screen"}, 
    {  0, 0} } ;
  char str1[200];

  sprintf(str1,"Project %s ", fileName);
  if(graphActivate(gsum)){
      graphClear();
      if (!nopop) graphPop();
  }
  else{                                /* x, y, w, h */    
      gsum = graphCreate (TEXT_FIT,str1,.6,.6,.68,.78) ;
      graphMenu (menu2) ;
  }
  graphRegister(RESIZE,sumresize);

  summary();
  return;
}

/**********************************************************
                    DEF: proj_seq
**********************************************************/
static void proj_seq()
{
CLONE *clp;
int status[10], ts[10], type[10], tt[10];
int c, i, n, cnt;

  for (i=0; i<10; i++) 
     ts[i]=tt[i]=0;

  for (n=0; n<= max_contig; n++)
  {
      if (contigs[n].count == 0) continue;
      for (i=0; i<10; i++) 
          type[i]=status[i]=0;
      cnt=0;
      for (c = contigs[n].start; c!=-1; c =  clp->next)
      {
         clp =  arrp(acedata, c, CLONE); 
         if (clp->seqstat!=0) {
            cnt++;
            for (i=1; i<seqstatnum; i++) 
               if (clp->seqstat==i) status[i]++;
         }
         if (clp->seqtype!=0) {
            if (clp->seqtype==FULLX) type[0]++;
            else if (clp->seqtype==HALFX) type[1]++;
            else if (clp->seqtype==GAPCLOSURE) type[2]++;
            else if (clp->seqtype==AUTOMATIC) type[3]++;
         }
      } 
      if (cnt == 0) Msg[0]='\0';
      else {
        for (i=0; i<4; i++) tt[i]+=type[i];
        for (i=0; i<seqstatnum; i++) ts[i]+=status[i];
      }
  }
  sprintf(Proj.msg2[0],
   "Tile %d Submit %d Ready %d Shotgun %d Finished %d SD %d",  
           ts[1], ts[2], ts[3], ts[4], ts[5], ts[6]);
  sprintf(Proj.msg2[1], 
   "Full-X %d Half-X %d Gap %d  Automatic %d", 
           tt[0], tt[1], tt[2], ts[3]);
}
/**********************************************************
                    DEF: summary
**********************************************************/
#define NUM 30
static int total[NUM], cloneclass[NUM], ctgclass[NUM], singleclass[NUM], class[NUM][NUM];

static void prtclass(float *line, int cl, char *name)
{
int i;
char str1[300], x[30];

  if (singleclass[cl]>0 || ctgclass[cl]>0) {
     for (str1[0]='\0', i=0; i<7; i++) {
         sprintf(x, "%5.1f ", 100.0 * ((float) class[cl][i]/
                      (float) (ctgclass[cl]+singleclass[cl])));
         strcat(str1, x);
     }
     sprintf(Msg,"%6s %6d %6d  %4.1f %s", name, ctgclass[cl], singleclass[cl], 
        (float) total[cl]/ (float)(ctgclass[cl]+singleclass[cl]), str1);
     graphText(Msg,1.0,*line); doline(0, 0,0,2,Msg);
     *line +=1.0;
  }
}

static void prtmarkclass(float *line, int cl, char *name)
{
int i;
float avg1, avg2;
char str1[300], str2[300], x[30];

  if (total[cl]>0) {
     for (str1[0]='\0', i=0; i<4; i++) {
         sprintf(x, "%4d ", class[cl][i]);
         strcat(str1, x);
     }
     avg1 = (float) ctgclass[cl]/(float) total[cl];
     for (str2[0]='\0'; i<8; i++) {
         sprintf(x, "%4d ", class[cl][i]);
         strcat(str2, x);
     }
     avg2 = (float) cloneclass[cl]/(float) total[cl];
     sprintf(Msg,"%6s %5d  %4.1f %s %4.1f %s", name, total[cl], avg1, str1, avg2, str2);
     graphText(Msg,1.0,*line); doline(0, 0,0,2,Msg);
     *line +=1.0;
  }
}

/* WMN 8/01/05 several changes to use %Q correctly - grep Pz.DQusePct */
static void summary()
{
CLONE *clp;
int i, j;
float  line=0.5;
int xctg1=0, xctg2=0;
int k, tmpb, b, ctg1=0, ctg2=0, ctg3=0, dist=0, seqctg=0, seqclone=0;
long int totseqdist=0, totseq=0, totclone=0, totctg=0, totqctg=0, totdist=0;
int zerofp=0, maxcontigs=0, maxclones=0;
int cancelled=0, cnt, totOlapMks=0, seqclctg=0;
struct marker *marker;
struct markerctgpos *ptr;
struct markerclone *mclp;
double size, clonesize=0.0, totalbandsize=0.0, pacsize=0.0, bacsize=0.0;
int start, save_dist=0, save_ctg = 0;
int totalseq = 0, paccnt=0, baccnt=0, clonecnt=0;
double f;
char space[5]="    ";
int bflag=0, avg=0, totbands=0, totclones=0, *bvals=NULL, exact=0, dup=0;
int smax=0, nosum=0, cntSTS=0, fw=0, place=0, abin[20], bin[20], qbin[20], sbin[20], gbin[20];
int totq5=0, totgt5=0, qnotknown=0;
int anchorclctg=0,*anchorctg=NULL,cntanchorctg=0;
int anchor_contig_len=0, chr_contig_len=0;
int ctg2chr=0;
int cntA=0, cntB=0, cntC=0;
int chr=0, *chrcnt=NULL, *chrlen=NULL;
float avgbands=0.0;
/* for maize only */
int dead=0, cl[12], pco[12], si[12], dd[12], sog[12];
int found, cati[12]={3,10,25, 50, 100, 200, 400, 600, 800, 1000, 1000};

  for (i=0; i<12; i++) cl[i]=pco[i]=si[i]=dd[i]=sog[i]=0;
  Proj.msg2[0][0]=Proj.msg2[1][0]='\0';
  numPL=0;
  
  sprintf(Msg, "FPC Project %s", fileName);
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line += 1.0;

  getdatehead(Msg);
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line += 1.0;

  graphLine(0.0,line+0.5,70,line+0.5); doline(0,0,0,2,space); line +=1.0;

  if (arrayExists(bands)) {
      bvals = (int *) malloc(sizeof(int) * bandmax+1);
      if (bvals==NULL) 
         fprintf(stderr,"Cannot allocate array from band values, continueing..\n");
      else {
         for (i=0;i<bandmax; i++) bvals[i]=0;
         bflag=1;
      }
  }
  for(i=0;i<arrayMax(acedata); i++) {
       if (arrp(acedata, i, CLONE)->clone[0]!='!')
        avgbands +=  arrp(acedata, i, CLONE)->fp->b2; 
  }
  avgbands /= arrayMax(acedata);

  for (i=0; i<NUM; i++) total[i]=ctgclass[i]=singleclass[i]=0;
  for (i=0; i<NUM; i++)  for (j=0; j<NUM; j++) class[i][j]=0;

                /* go through clones */
  for(i=0;i<arrayMax(acedata); i++)
  { 
      clp =  arrp(acedata, i, CLONE);
      if (clp->clone[0] == '!') {
          cancelled++;
          continue;
      }
      if (clp->clone[0] == 'a') cntA++; 
      if (clp->clone[0] == 'b') cntB++; 
      if (clp->clone[0] == 'c') cntC++; 
      if (clp->fp==NULL || clp->fp->b2==0) {
          zerofp++;
          continue;
      }
      if (NoSum(clp->ctg)) {
          nosum++;
          continue;
      }
      totclones++;
      if(clp->ctg != 0 && clp->ctg <= max_contig){ 
         ctgclass[clp->class]++;
         xctg2++;
      }
      else {
         singleclass[clp->class]++;
         xctg1++;
      }

      if (bflag) {
          start = clp->fp->b1;
          for (tmpb=-1, size=0.0, j=0; j < clp->fp->b2; j++) {
             b = arr(bands, start + j - 1, int);
             if (bvals!=NULL) bvals[b]++;
             size += (float) b;
             if (tmpb==b) exact++;
             if (abs(tmpb-b) <= Pz.tol) dup++;
             tmpb = b;
          }
          if (clp->class==TYPEBAC) {baccnt++; bacsize += size;}
          else if (clp->class==TYPEPAC) {paccnt++; pacsize += size;}
          else {clonecnt++; clonesize+=size;}
          totalbandsize += size;
          totbands += clp->fp->b2;
      }
    
      if (avgbands>75.0) {
         if (clp->fp->b2 < 60) class[clp->class][0]++; 
         else if (clp->fp->b2 < 80) class[clp->class][1]++;
         else if (clp->fp->b2 < 100) class[clp->class][2]++; 
         else if (clp->fp->b2 < 120) class[clp->class][3]++; 
         else if (clp->fp->b2 < 140) class[clp->class][4]++; 
         else if (clp->fp->b2 < 160) class[clp->class][5]++; 
         else class[clp->class][6]++;  
      }
      else {
         if (clp->fp->b2 < 5) class[clp->class][0]++; 
         else if (clp->fp->b2 < 15) class[clp->class][1]++;
         else if (clp->fp->b2 < 25) class[clp->class][2]++; 
         else if (clp->fp->b2 < 35) class[clp->class][3]++; 
         else if (clp->fp->b2 < 45) class[clp->class][4]++; 
         else if (clp->fp->b2 < 55) class[clp->class][5]++; 
         else class[clp->class][6]++;  
      } 
      total[clp->class] += clp->fp->b2;
  }
             /* print clone summary */
  sprintf(Msg, "Clones Total %d", arrayMax(acedata));
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line +=1.0;

  if (cancelled>0 || zerofp > 0 || nosum > 0) {
    sprintf(Msg, "Good %d  Cancelled %d  NoFp %d InDeadAvoidCTG %d",
             totclones, cancelled, zerofp, nosum);
    graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line +=1.0;
  }
  doline(0, 0,0,2,space); line +=1.0;
#ifdef AGI 
  sprintf(Msg, "LibA %d LibB %d LibC %d", cntA, cntB, cntC);
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line +=1.0;
#endif

  if (!bflag) goto AFTERBAND;

  if (Proj.variable) {
       float  fd1=0.0, fd2=0.0, fd3=0.0;
       int s1=0, d1=0, s2=0, d2=0, s3=0, d3=0;
       if (baccnt!=0) s1= (int) (bacsize/(float)baccnt);
       if (paccnt!=0) s2= (int) (pacsize/(float)paccnt);
       if (clonecnt!=0) s3= (int) (clonesize/(float)clonecnt);

       for (i=0; i<arrayMax(acedata); i++) {
          clp = arrp(acedata,i,CLONE);
          if (clp->clone[0] == '!' || clp->fp==NULL || clp->fp->b2==0) continue;
          start = clp->fp->b1;
          for (size=0.0, j=0; j < clp->fp->b2; j++) {
             b = arr(bands, start + j - 1, int);
             size += (float) b;
          }
          if (clp->class==TYPEBAC) fd1 += (double) abs(s1-size);
          else if (clp->class==TYPEPAC) fd2 += (double) abs(s2-size);
          else fd3 += (double) abs(s3-size);
       }
       if (baccnt!=0) d1= (int) (fd1/(double)baccnt);
       if (paccnt!=0) d2= (int) (fd2/(double)paccnt);
       if (clonecnt!=0) d3= (int) (fd3/(double)clonecnt);
       graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;
   }
   avg =  (int)(totalbandsize/totbands);
   if (Proj.variable) sprintf(Msg, 
       "Average Band Size %d Average Doublet %3.1f  Exact %3.1f", 
            avg, (float) dup/(float)totclones, (float)exact/(float)totclones);
   else sprintf(Msg, 
       "Average Band Rate %d Average Doublet %3.1f  Exact %3.1f", 
             avg, (float) dup/(float)totclones, (float)exact/(float)totclones);
   graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;
   doline(0, 0,0,2,space); line+=1.0;
   free(bvals);

AFTERBAND: ;
  sprintf(Msg, "                      Percentage of bands");
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line +=1.0;

  if (avgbands>75.0)
     sprintf(Msg, " Class Contig Single   Avg   <60  <80   <100  <120  <140  <160  >=160");
  else
     sprintf(Msg, " Class Contig Single   Avg    <5   <15   <25   <35   <45   <55  >=55");
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line +=1.0;

  prtclass(&line, TYPECOSMID, "Cosmid");
  prtclass(&line, TYPEFOSMID, "Fosmid");
  prtclass(&line, TYPEBAC, "BAC");
  prtclass(&line, TYPEPAC, "PAC");
  prtclass(&line, TYPEYAC, "YAC");
  prtclass(&line, TYPECLONE, "Clone");
  graphLine(0.0,line+0.5,70,line+0.5); doline(0,0,0,2,space); line +=1.0;

  if (arrayMax(markerdata)==0) {
    graphText("No markers",1.0,line);doline(0,0,0,2,"No markers"); line +=1.0;
    goto SEQ;
  }
  for (i=0; i<NUM; i++) total[i]=ctgclass[i]=cloneclass[i]=0;
  for (i=0; i<NUM; i++)  for (j=0; j<NUM; j++) class[i][j]=0;;
  ctg1=ctg2=0;

/* MARKERS */

  anchorctg = malloc((max_contig+2)*sizeof(int));
  NOMEM2(anchorctg, "anchorctg");
  for (i=0; i<=max_contig;i++) anchorctg[i]=0;
  for(i=0;i<arrayMax(markerdata); i++)
  {
      marker = arrp(markerdata, i, MARKER);
      total[marker->type]++;
      if (marker->anchor_pos > FLT_MIN) {
          if (marker->frame_type == FRAME) fw++;
          else place++;
      }
      cnt=0;
      for (ptr = marker->pos; ptr!=NULL; ptr=ptr->next){
           if (ptr->ctg!=0) {
              cnt++;
              if (marker->anchor_pos > FLT_MIN && ptr->ctg<=max_contig) 
                  anchorctg[ptr->ctg]++;
/*              if (strcmp(fileName,"maize")==0) {
                  if (strstr(contigs[ptr->ctg].chr_msg,"Chr")!=NULL) {
                     sscanf(contigs[ptr->ctg].chr_msg,"Chr%d",&chr);
                     if (strstr(marker->marker,"CL")==marker->marker) cl[chr]++;
                     if (strstr(marker->marker,"PCO")==marker->marker) pco[chr]++;
                     if (strstr(marker->marker,"si")==marker->marker) si[chr]++;
                     if (strstr(marker->marker,"dd")==marker->marker) dd[chr]++;
                     if (strstr(marker->marker,"SOG")==marker->marker) sog[chr]++;
                     if (strstr(marker->marker,"AOG")==marker->marker) sog[chr]++;
                  }
              }
*/ /* WMN Jan '10 */
           }
      }
      if ( marker->nextclone!=NULL) { /* This means it hits more than one clone */
         if (cnt==0) ctg1++;
         else if (cnt==1) ctg2++;
         else ctg3++;
      }
      if (cnt<3) class[marker->type][cnt]++;
      else class[marker->type][3]++;
      ctgclass[marker->type] += cnt;
      maxcontigs = MaX(cnt, maxcontigs);

      cnt=1;
      for (mclp = marker->nextclone; mclp!=NULL; mclp = mclp->nextclone)
            cnt++;
      maxclones = MaX(cnt, maxclones);
      cloneclass[marker->type] += cnt;
      if (cnt==1) class[marker->type][4]++;
      else if (cnt<5) class[marker->type][5]++;
      else if (cnt<10) class[marker->type][6]++;
      else  class[marker->type][7]++;
      if (marker->type==markSTS) cntSTS++;
  }
  if (fw>0 && place > 0) sprintf(Msg, "Markers %d  Anchors %d (FW %d Place %d)", 
                     arrayMax(markerdata), fw+place, fw, place);
  else if (fw>0 || place > 0) sprintf(Msg, "Markers %d  FW %d", 
                     arrayMax(markerdata), fw+place);
  else sprintf(Msg, "Markers %d", arrayMax(markerdata));
  graphText(Msg,1.0,line); doline(0,0,0,2,Msg); line +=1.0;

  totOlapMks=ctg1+ctg2+ctg3;
  sprintf(Msg, "MHM %d: 0 ctgs %d, 1 ctg %d, >1 ctg %d", 
       totOlapMks, ctg1, ctg2,ctg3);
  graphText(Msg,1.0,line); doline(0,0,0,2,Msg); line+=1.0;
  doline(0,0,0,2,space); line +=1.0;

  sprintf(Msg, "              Number of contigs         Number of clones");
  graphText(Msg,1.0,line); doline(0,0,0,2,Msg); line +=1.0;

  sprintf(Msg, "Class  Total   Avg   =0   =1   =2   >2   Avg   =1   <5  <10 >=10");
  graphText(Msg,1.0,line); doline(0,0,0,2,Msg); line +=1.0;

  prtmarkclass(&line, markPCR, "ePCR");
  prtmarkclass(&line, markeBAC, "eBAC");
  prtmarkclass(&line, markeMRK, "eMRK");
  prtmarkclass(&line, markPROBE, "Probe");
  prtmarkclass(&line, markSTS, "STS");
  prtmarkclass(&line, markCDNA, "cDNA");
  prtmarkclass(&line, markEND, "End");
  prtmarkclass(&line, markCOSMID, "Cosmid");
  prtmarkclass(&line, markFOSMID, "Fosmid");
  prtmarkclass(&line, markBAC, "BAC");
  prtmarkclass(&line, markPAC, "PAC");
  prtmarkclass(&line, markYAC, "YAC");
  prtmarkclass(&line, markCLONE, "Clone");
  prtmarkclass(&line, markLOCUS, "Locus");
  prtmarkclass(&line, markTC, "TC");
  prtmarkclass(&line, markSSR, "SSR");
  prtmarkclass(&line, markRFLP, "RFLP");
  prtmarkclass(&line, markREP, "REP");
  prtmarkclass(&line, markOVERGO, "OVERGO");
  prtmarkclass(&line, markSNP, "SNP");
SEQ: ;
  graphLine(0.0,line+0.5,70,line+0.5); doline(0,0,0,2,space); line +=1.0;

/* SEQUENCE */
  for(i=0;i<=max_contig;i++) totalseq += contigs[i].seq;

  if (totalseq==0) {
    graphText("No sequenced clones",1.0,line); 
    doline(0,0,0,2,"No sequenced clones"); line +=1.0;
  }
  else {
     sprintf(Msg, "Sequenced %d", totalseq);
     graphText(Msg,1.0,line); doline(0,0,0,2,Msg); line +=1.0;
     proj_seq();
   
     graphText(Proj.msg2[0],1.0,line); doline(0,0,0,2,Proj.msg2[0]); line+=1.0;
     graphText(Proj.msg2[1],1.0,line); doline(0,0,0,2,Proj.msg2[1]); line+=1.0;
  } 
  graphLine(0.0,line+0.5,70,line+0.5); doline(0,0,0,2,space); line +=1.0;

/* CONTIGS */
  if (strcmp(fileName, mapname)==0 && numchr>0) {
     chrlen = malloc((numchr+1)*sizeof(int));
     NOMEM2(chrlen, "chrlen");
     chrcnt = malloc((numchr+1)*sizeof(int));
     NOMEM2(chrcnt, "chrcnt");
     for (i=0; i<numchr; i++) chrlen[i]=chrcnt[i]=0;
  } 
  for (i=0;i<20;i++) gbin[i]=bin[i]=sbin[i]=abin[i]=qbin[i]=0;
  for (i=1; i <= max_contig; i++) 
  {
       if (contigs[i].count==0) continue;
       if (NoSum(i)) {
           dead++;  /* cari 7-5-4 */
           continue;
       } 
       /* bin contigs based on number of clones */
       for (found=k=0; k< 10 && !found; k++)
         if (contigs[i].count < cati[k]) { 
                found=1;
                bin[k]++;
                if (Pz.DQusePct == 0) {
                   if (contigs[i].ctgQs > Pz.DQnumq) qbin[k]++;
                }
                else {
                   if ( ((float)contigs[i].ctgQs)/((float)contigs[i].count) > ((float)Pz.DQnumq)/100.0) qbin[k]++;
                }
                if (contigs[i].seq > 0) sbin[k]++;
                if (anchorctg!=NULL && anchorctg[i]) abin[k]++;
                if (strncmp(contigs[i].chr_msg,Proj.label_abbrev,2)==0) gbin[k]++;
         }
       if (!found) { /* > 1000 */
            bin[k]++;
            if (contigs[i].ctgQs > Pz.DQnumq) qbin[k]++;
            if (contigs[i].seq > 0) sbin[k]++;
            if (anchorctg!=NULL && anchorctg[i]) abin[k]++;
            if (strncmp(contigs[i].chr_msg,Proj.label_abbrev,2)==0) gbin[k]++;
       }

       /* find contig with most Qs, most clones, and longest */
       if (contigs[i].ctgQs== -1) qnotknown++;
       else if (contigs[i].ctgQs> 0) {
            totqctg++;
            if (0 == Pz.DQusePct) {
                if (contigs[i].ctgQs <= Pz.DQnumq) totq5++;
                else totgt5++;
            }
            else {
                if (contigs[i].ctgQs <= ((float)Pz.DQnumq)*((float)(contigs[i].count)/100.0)) totq5++;
                else totgt5++;
            }
       }
       dist = contigs[i].right - contigs[i].left + 1;
       if (dist > save_dist) {
           save_dist = dist;
           save_ctg = i;
       }
       totctg++;
       totdist += dist;
       totclone += contigs[i].count;

       /* get sequence stats */
       if (contigs[i].seq > 0) {
          int isSeqCtg=0, left=INT_MAX, right=INT_MIN;
          for (j=contigs[i].start; j != -1; j = clp->next)
          {
              clp = arrp(acedata,j,CLONE);
              if (IsSeq(clp)) {
                  left = MiN(left,clp->x);
                  right = MaX(right,clp->y);
                  seqclone++;
                  isSeqCtg=1;
              }
           }
           if (isSeqCtg) {
              totseq += (right - left+1);
              totseqdist += dist;
              seqctg++;
              seqclctg += contigs[i].count;
              smax = MaX(smax, contigs[i].count);
           }
       }

       if (anchorctg!=NULL && anchorctg[i]) {
          cntanchorctg++;
          anchorclctg+=contigs[i].count;
          anchor_contig_len += dist;
       }

         /* count number of contigs with chromosome assignments */
       if (strstr(contigs[i].chr_msg,Proj.label_abbrev)!=NULL)
       {
           ctg2chr++;
           chr_contig_len += dist;
           if (chrcnt!=NULL) { /* MAIZE */
              sscanf(contigs[i].chr_msg,"Chr%d",&chr);
              if (chr>0 && chr<numchr) {
                 chrcnt[chr]++;
                 chrlen[chr] += dist;
              }
              else printf("Bad chr %d\n",chr);
           }
       }
  }
  sprintf(Msg, "Contigs %ld  Dead contigs %d  Singles %d", 
               totctg,dead,xctg1); doline(0,0,0,2,Msg);
  graphText(Msg,1.0,line); line++;
  if (0 == Pz.DQusePct) {
     sprintf(Msg, "Q-Contigs %ld  Unknown %d  Qs<=%d %d  Qs>%d %d", 
               totqctg,qnotknown,Pz.DQnumq, totq5, Pz.DQnumq, totgt5);
  }
  else {
     sprintf(Msg, "Q-Contigs %ld  Unknown %d  Qs<=%d%% %d  Qs>%d%% %d", 
               totqctg,qnotknown,Pz.DQnumq, totq5, Pz.DQnumq, totgt5);
  }
  doline(0,0,0,2,Msg);
  graphText(Msg,1.0,line); 
  if (seqctg!=0) {
    line += 1.0;
    sprintf(Msg, "SequencedContigs %-4d  Clones in contigs %d ",
                   seqctg, seqclctg); doline(0,0,0,2,Msg);
    graphText(Msg,1.0,line); 
  }
  if (cntanchorctg!=0) {
    line += 1.0;
    sprintf(Msg, "Anchored Contigs %-4d  Clones in contigs %d ",
                   cntanchorctg, anchorclctg); doline(0,0,0,2,Msg);
    graphText(Msg,1.0,line); 
  }
  if (ctg2chr!=0) {
    line += 1.0;
    sprintf(Msg, "Contigs assigned to chromosomes %d", ctg2chr); doline(0,0,0,2,Msg);
    graphText(Msg,1.0,line); 
  }
  doline(0,0,0,2,space);
  line += 1.0;

/* TABLE */
  doline(0,0,0,2,space); line += 1.0;
  sprintf(Msg, "Range     INF   %d  %d  %d  %d  %d   %d   %d   %d    %d     ",
       cati[9]-1,cati[8]-1,cati[7]-1,cati[6]-1,cati[5]-1,
       cati[4]-1,cati[3]-1,cati[2]-1,cati[1]-1);
  graphText(Msg,1.0,line); line += 1.0; doline(0,0,0,2,Msg);
  sprintf(Msg, "      ---%d---%d--%d--%d--%d--%d---%d---%d---%d----%d-- =2",
       cati[9], cati[8],cati[7],cati[6],cati[5],cati[4],cati[3],cati[2],cati[1],cati[0]);
  graphText(Msg,1.0,line); line += 1.0; doline(0,0,0,2,Msg);

  sprintf(Msg, "Contig  %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
   bin[10], bin[9], bin[8], bin[7], bin[6], bin[5], bin[4], bin[3], bin[2],bin[1],bin[0]);
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;

  if (0 == Pz.DQusePct) {
    sprintf(Msg, ">%2d  Qs %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
       Pz.DQnumq, qbin[10], qbin[9], qbin[8], qbin[7], qbin[6], qbin[5], qbin[4], qbin[3],
                  qbin[2], qbin[1], qbin[0]);
  }
  else {
    sprintf(Msg, ">%2d%% Qs %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
       Pz.DQnumq, qbin[10], qbin[9], qbin[8], qbin[7], qbin[6], qbin[5], qbin[4], qbin[3],
                  qbin[2], qbin[1], qbin[0]);
  }
  graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;

  if (seqctg!=0) {
    sprintf(Msg, "Seq     %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
         sbin[10], sbin[9], sbin[8], sbin[7], sbin[6], sbin[5], 
          sbin[4], sbin[3], sbin[2],sbin[1],sbin[0]);
    graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;
  }
  if (cntanchorctg!=0) {
    sprintf(Msg, "Anchor  %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
         abin[10], abin[9], abin[8], abin[7], abin[6], abin[5], 
          abin[4], abin[3], abin[2],abin[1],abin[0]);
    graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;
  }
  if (Proj.label_abbrev[0]!='\0') {
    sprintf(Msg, "%-7s %5d %5d %4d %4d %4d %4d %4d %4d %4d %4d %4d",
         Proj.label_abbrev,gbin[10], gbin[9], gbin[8], gbin[7], gbin[6], gbin[5], 
          gbin[4], gbin[3], gbin[2],gbin[1],gbin[0]);
    graphText(Msg,1.0,line); doline(0, 0,0,2,Msg); line+=1.0;
  }
 

/* FINAL STATS */
  {
    float   E;
    float  G=Proj.genomesize;
    int B=Proj.avgbandsize;
    int In=Proj.avginsertsize;
  
    graphLine(0.0,line+0.5,70,line+0.5); doline(0,0,0,2,space); 
    if (In==0) In=Proj.avginsertsize=160000;
    if (B==0) B = Proj.avgbandsize = 4082;
    sprintf(Msg, "If Average Band Size %d" , B);
    line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
    sprintf(Msg, "                  Bands    Coverage");
    line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);

    f = ((double) totdist * (double) B)/1000.0;
    sprintf(Msg, "Total Contigs    %6ld %8d kb", totdist, (int) f);
    line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);

    f = ((double) save_dist * (double) B)/1000.0;
    sprintf(Msg, "Longest Ctg%-5d %6d %8d kb  ", save_ctg,save_dist, (int) f);
    line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
    if (seqctg!=0) {
      f = ((double) totseqdist * (double) B)/1000.0;
      sprintf(Msg, "Sequence Contigs %6ld %8d kb", totseqdist, (int) f);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);

      f = ((double) totseq * (double) B)/1000.0;
      sprintf(Msg, "Total Sequence   %6ld %8d kb", totseq, (int) f);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
    }
    if (cntanchorctg!=0) {
      f = ((double) anchor_contig_len * (double) B)/1000.0;
      sprintf(Msg, "Total Anchor     %6d %8d kb", anchor_contig_len, (int) f);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      f = ((double) chr_contig_len * (double) B)/1000.0;
      sprintf(Msg, "Total Assigned   %6d %8d kb", chr_contig_len, (int) f);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
    }
    if (G!=0) {
      E = (In * (float) totclones)/(float) G; 
      line+=1.0; doline(0, 0,0,2,space); 
      sprintf(Msg, "If Genome %ld kb Insert %d then Coverage %dx ", 
                (unsigned long int) (G/1000), (int) In, (int) E);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      if (cntSTS>0) i = (int)((float)G/(float) cntSTS)/1000.0;
      else i=0;
      if (fw>0 || place>0) j = (int)((float)G/(float) (fw+place))/1000.0;
      else j=0;
      if (totOlapMks>0) k = (int)((float)G/(float) (totOlapMks))/1000.0;
      else k=0;
      sprintf(Msg,"  One MHM per %d kb  One STS per %d kb  One FW per %d kb",
            k, i,j);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      E = (In * (float) seqclctg)/(float) G; 
      f = (((double) totseq * (double) B)/(float) G) * 100.0;
      sprintf(Msg,"  Percent of genome sequenced %d  Coverage  %dx", 
                       (int) f, (int) E);
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
    }
  }
  if (chrcnt!=NULL) {
      float a, b;
      line += 1.0; doline(0, 0,0,2, space);
      sprintf(Msg,"Chr  Contigs  Length  Real    Percent  CL   PCO    si    dd   SOG");
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      sprintf(Msg,"               (kb)   (kb)        ");
      line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      for (i=1; i<numchr; i++) {
         a = (float) (chrlen[i]*Proj.avgbandsize)/1000;
         b = chrsize[i]*1000;
         sprintf(Msg,"%2d    %3d     %6d  %6d  %3.3f  %4d  %4d  %4d  %4d  %4d", 
             i, chrcnt[i], (int) a, (int) b, a/b, cl[i],pco[i],si[i],dd[i],sog[i]);
         line += 1.0; graphText(Msg,1.0,line); doline(0, 0,0,2,Msg);
      }
      free(chrlen); free(chrcnt);
  }
  graphRedraw();
}
